package com.sunrise.crm.repositorio;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.sunrise.crm.repositorio.iface.UsuarioDao;
import com.sunrise.generico.acesso.DaoService;
import com.sunrise.generico.entidade.Filial;
import com.sunrise.generico.entidade.Usuario;
import com.sunrise.generico.visao.Filtro;

@Repository
public class UsuarioDaoImpl extends DaoService<Usuario> implements UsuarioDao {

	public List<Usuario> listarOrdenado() {
		List<Usuario> list = listar(Usuario.class);
		Collections.sort(list, new Comparator<Usuario>() {

			@Override
			public int compare(Usuario o1, Usuario o2) {
				return o1.getNome().compareTo(o2.getNome());
			}
		});
		return list;
	}

	public List<Usuario> search(Usuario ex) {
		List<Usuario> list = searchByExample(Usuario.class, ex);
		Collections.sort(list, new Comparator<Usuario>() {

			@Override
			public int compare(Usuario o1, Usuario o2) {
				return o1.getNome().compareTo(o2.getNome());
			}
		});
		return list;
	}

	public Usuario getById(Long id) {
		return getById(id, Usuario.class);
	}

	public List<Usuario> searchByExample(Usuario example) {
		List<Usuario> list = searchByExample(Usuario.class, example);
		Collections.sort(list, new Comparator<Usuario>() {

			@Override
			public int compare(Usuario o1, Usuario o2) {
				return o1.getNome().compareTo(o2.getNome());
			}
		});
		return list;
	}

	public Usuario buscarPorUsername(String userNome) {
		Criteria crit = getSession().createCriteria(Usuario.class);
		crit.add(Restrictions.eq("username", userNome).ignoreCase());
		return (Usuario) crit.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Usuario> listarPorNome(String nome) {
		Criteria crit = getSession().createCriteria(Usuario.class);
		crit.add(Restrictions.ilike("nome", nome, MatchMode.ANYWHERE));
		return crit.list();
	}

	@Override
	public Usuario buscarPorNome(String nome) {
		Criteria crit = getSession().createCriteria(Usuario.class);
		crit.add(Restrictions.eq("nome", nome).ignoreCase());
		return (Usuario) crit.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Usuario> buscarPorFiltros(Filtro filtro) {
		Criteria crit = getSession().createCriteria(Usuario.class);
		if (filtro.getNome() != null && !filtro.getNome().isEmpty()) {
			crit.add(Restrictions.eq("nome", filtro.getNome()));
		}

		if (filtro.getCpf() != null && !filtro.getCpf().isEmpty()) {
			crit.add(Restrictions.eq("cpf", filtro.getCpf()));
		}

		if (filtro.getEmail() != null && !filtro.getEmail().isEmpty()) {
			crit.add(Restrictions.eq("email", filtro.getEmail()));
		}

		if (filtro.getAtivo() != null) {
			crit.add(Restrictions.eq("ativo", filtro.getAtivo().getCodigo()));
		}

		crit.addOrder(Order.asc("nome"));
		return crit.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<Usuario> listarPorPerfil(Long perfil) {
		Criteria crit = getSession().createCriteria(Usuario.class);
		crit.add(Restrictions.eq("perfil.id", perfil));
		return crit.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<Usuario> listarPorNomeFilial(String nome, Filial filial) {
		Criteria crit = getSession().createCriteria(Usuario.class);
		if (nome != null && !nome.isEmpty()) {
			crit.add(Restrictions.eq("nome", nome));
		}

		if (filial != null && filial.getId() != null) {
			crit.createAlias("filais", "filial");
			crit.add(Restrictions.eq("filial.id", filial.getId()));
		}

		crit.addOrder(Order.asc("nome"));
		return crit.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<Usuario> listarPorLoginEmail(String login) {
		Criteria crit = getSession().createCriteria(Usuario.class);
		crit.add(Restrictions.or(Restrictions.eq("username", login).ignoreCase(), Restrictions.eq("email", login)
				.ignoreCase()));
		return crit.list();
	}

}
